from django.test import TestCase
from django.test.client import Client
from django.conf import settings
from django.core.urlresolvers import reverse
from studenthoods.apps.facebook.models import Entrant, FacebookCompetition, University
from django.template.defaultfilters import slugify

from datetime import date
import random, uuid

class CompetitionTest(TestCase):
    def setUp(self):
        self.client = Client()
        self.university = create_university()
        self.competition = create_competition(self.university)
        
    def test_competition(self):
        response = self.client.get(reverse('facebook_comp', args=[self.competition.app_id]))
        self.assertContains(response, '', None, status_code=200)
        
    def test_competition_fail_bad_name(self):
        response = self.client.get(reverse('facebook_comp', args=[u'boom']))
        self.assertContains(response, '', None, status_code=404)

    def test_competition_over(self):
        self.competition.closing_date = date(2012, 1, 1)
        self.competition.save()
        response = self.client.get(reverse('facebook_comp', args=[self.competition.app_id]))
        self.assertContains(response, '<title>Competition is closed | Student Hoods</title>', 1, status_code=200)


class EmailConfirmTest(TestCase):
    def setUp(self):    
        self.client = Client()
        self.university = create_university()
        self.competition = create_competition(self.university)

    def test_match(self):
        response = self.client.post(reverse('facebook_comp', args=[self.competition.app_id]), {
            'email' : 'test@example.org',
            'confirm_email' : 'test@example.org',
            }
        )

        self.assertNotContains(
            response,
            'Your Confirmation Email does not match your original Email.'
        )

    def test_not_match(self):
        response = self.client.post(reverse('facebook_comp', args=[self.competition.app_id]), {
            'email' : 'test@example.org',
            'email_confirm' : 'nottest@example.org',
            }
        )

        self.assertFormError(
            response,
            'form',
            'email_confirm',
            'Your Confirmation Email does not match your original Email.'
        )

class DuplicateEntryTest(TestCase):

    def setUp(self):
        self.client = Client()
        self.university = create_university()
        self.competition = create_competition(self.university)
        self.entrant = create_entrant(self.competition, self.university)

    def test_duplicate_signup(self):
        response = self.client.post(reverse('facebook_comp', args=[self.competition.app_id]), {
            'email' : 'joe@example.com',
            }
        )

        self.assertFormError(
            response,
            'form',
            'email',
            'This Email Address is already entered'
        )

    def test_valid_email(self):
        response = self.client.post(reverse('facebook_comp', args=[self.competition.app_id]), {
            'email' : 'nottest@example.org',
            }
        )
        
        self.assertFormError(
            response,
            'form',
            't_and_cs',
            'Please agree to the Terms and Conditions'
        )


        self.assertNotContains(
            response,
            'This Email Address is already entered'
        )

class SuccessfulEntrantTest(TestCase):
    def setUp(self):
        self.client = Client()
        self.university = create_university()
        self.competition = create_competition(self.university)

    def test_successful_entry(self):

        response = self.client.post(reverse('facebook_comp', args=[self.competition.app_id]), {
            'name' : 'Frank Bobbins',
            'email' : 'seb@sebashton.com',
            'email_confirm' : 'seb@sebashton.com',
            'size' : 'M',
            't_and_cs' : True,
            }
        )

        self.assertContains(response, 'You were entered into the prize draw.', 1, status_code=200)


class EntrySavedTest(TestCase):
    def setUp(self):
        self.client = Client()
        self.university = create_university()
        self.competition = create_competition(self.university)

    def test_entry_saved(self):
        initial_count = len(Entrant.objects.all())

        response = self.client.post(reverse('facebook_comp', args=[self.competition.app_id]), {
            'name' : 'Frank Bobbins',
            'email' : 'seb@sebashton.com',
            'email_confirm' : 'seb@sebashton.com',
            'size' : 'M',
            't_and_cs' : True,
            }
        )

        post_count = len(Entrant.objects.all())

        self.assertEqual(initial_count+1, post_count)


class FacebookShareTest(TestCase):
    def setUp(self):
        self.client = Client()

    def test_app_id(self):
        university = create_university()
        competition = create_competition(university)
        response = self.client.get(reverse('facebook_comp', args=[competition.app_id]))
        self.assertContains(response, 'app_id: "'+competition.app_id+'"', 1, status_code=200)

    def test_app_link(self):
        university = create_university()
        competition = create_competition(university)
        response = self.client.get(reverse('facebook_comp', args=[competition.app_id]))
        self.assertContains(response, 'link: "'+settings.SOCIAL_FACEBOOK+'?sk=app_'+competition.app_id+'"', 1, status_code=200)

    def test_caption(self):
        university = create_university()
        competition = create_competition(university)
        response = self.client.get(reverse('facebook_comp', args=[competition.app_id]))
        self.assertContains(response, university.facebookShareCaption, 1, status_code=200)


    def test_decription(self):
        university = create_university()
        competition = create_competition(university)
        response = self.client.get(reverse('facebook_comp', args=[competition.app_id]))
        self.assertContains(response, university.facebookShareDescription, 1, status_code=200)


def create_competition(university):
    competition = FacebookCompetition()
    competition.app_id = str(create_random_alphanumeric())
    competition.app_secret = str(create_random_alphanumeric())
    competition.opening_date = date.today()
    competition.closing_date = date.today()

    competition.university = university
    competition.save()
    return competition

def create_university():
    university = University()
    university.name = 'University '+ str(random.random())
    university.slug = slugify(university.name)
    university.facebookPageUrl = 'http://www.example.com'
    university.hoodySizeGuideUrl = 'http://www.example.com'
    university.facebookShareCaption = 'Nullam id dolor id nibh ultricies vehicula ut id elit.'
    university.facebookShareDescription = 'Donec id elit non mi porta gravida at eget metus. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras mattis consectetur purus sit amet fermentum.'
    university.fullSizeLink = 'http://www.example.com'
    university.terms = 'http://www.example.com'
    university.orderFromHere = 'http://www.example.com'
    university.save()
    return university

def create_entrant(competition, university):
    entrant = Entrant()
    entrant.name = 'Joe Bloggs'
    entrant.email = 'joe@example.com'
    entrant.size = 'M'
    entrant.university = university
    entrant.competition = competition
    entrant.save()
    return entrant

def create_random_alphanumeric():
    uid = uuid.uuid4()
    return uid.hex